package com.zdp.future;

import com.google.common.util.concurrent.*;

import java.util.concurrent.Callable;
import java.util.concurrent.Executor;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

public class GuavaFutureTest {
    public static final int SLEEP_GAP = 500;
    public static void main(String args[]) {
        //创建一个新的线程实例，作为泡茶主线程
        MainJob mainJob = new MainJob();
        Thread mainThread = new Thread(mainJob);
        mainThread.setName("主线程");
        mainThread.start();

        //烧水的业务逻辑实例
        Callable<Boolean>hotJob = new HotWaterJob();
        //清洗的业务逻辑实例
        Callable<Boolean>washJob = new WashJob();

        //创建Java线程池
        ExecutorService jPool = Executors.newFixedThreadPool(10);
        //包装Java线程池，构造Guava线程池
        ListeningExecutorService gPool
                = MoreExecutors.listeningDecorator(jPool);

        //提交烧水的业务逻辑实例，到Guava线程池获取异步任务
        ListenableFuture<Boolean>hotFuture = gPool.submit(hotJob);
        //绑定异步回调，烧水完成后，把喝水任务的warterOk标志设置为true
        Futures.addCallback(hotFuture, new FutureCallback<Boolean>() {
            public void onSuccess(Boolean r) {
                if (r) {
                    System.out.println("水烧完了");
                    mainJob.warterOk = true;
                }
            }
            public void onFailure(Throwable t) {
                System.out.println("烧水失败，没有茶喝了");
            }
        },gPool);
        //提交清洗的业务逻辑实例，到Guava线程池获取异步任务
        ListenableFuture<Boolean>washFuture = gPool.submit(washJob);
        //绑定任务执行完成后的回调逻辑到异步任务
        Futures.addCallback(washFuture, new FutureCallback<Boolean>() {
            public void onSuccess(Boolean r) {
                if (r) {
                    System.out.println("杯子洗完了");
                    mainJob.cupOk = true;
                }
            }
            public void onFailure(Throwable t) {
                System.out.println("杯子洗不了，没有茶喝了");
            }
        },gPool);
    }
    // 烧水逻辑
    static class HotWaterJob implements Callable<Boolean> {

        @Override
        public Boolean call() throws Exception {
            System.out.println("烧水");
            Thread.sleep(5000);
            return true;
        }
    }
    // 清洗逻辑
    static class WashJob implements Callable<Boolean> {

        @Override
        public Boolean call() throws Exception {
            System.out.println("清洗");
            Thread.sleep(5000);
            return true;
        }
    }
    // 喝茶逻辑
    static class MainJob implements Runnable {
        boolean warterOk = false;
        boolean cupOk = false;
        int gap = SLEEP_GAP / 10;
        @Override
        public void run() {
            while (true) {
                try {
                    Thread.sleep(gap);
                    System.out.println("读书中．.....");
                } catch (InterruptedException e) {
                    System.out.println(Thread.currentThread().getName() + "发生异常中断");
                }
                if (warterOk&&cupOk) {
                    if(drinkTea(warterOk, cupOk)){
                        break;
                    }
                }
            }
        }

        public boolean drinkTea(Boolean wOk, Boolean cOK) {
            if (wOk&&cOK) {
                System.out.println("泡茶喝，茶喝完");
                this.warterOk = false;
                this.gap = GuavaFutureTest.SLEEP_GAP * 100;
                return true;
            } else if (! wOk) {
                System.out.println("烧水失败，没有茶喝了");
                return false;
            } else if (! cOK) {
                System.out.println("杯子洗不了，没有茶喝了");
                return false;
            }
            return false;
        }
    }
}
